package MenuPrincipal;

import Figuras.Circulo;
import Figuras.ComponenteGenerico;
import Figuras.Linea;
import Figuras.Rectangulo;
import JDBC.ConexionJDBCMySQL;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;



public class PantallaParaDibujar extends javax.swing.JPanel{
  
    public static final int MAXIMO_LARGO_PANTALLA_DIBUJO = 1024;
    public static final int MAXIMO_ANCHO_PANTALLA_DIBUJO = 1024;
    public static final int MINIMO_LARGO_PANTALLA_DIBUJO = 0;
    public static final int MINIMO_ANCHO_PANTALLA_DIBUJO = 0;
    public static final int MARGEN_ANCHO_PANTALLA_DIBUJO = 50;
    public static final int MARGEN_LARGO_PANTALLA_DIBUJO = 120;
    private final static int Circulo = 1, Rectangulo = 2, Linea = 3, ARRASTRAR = 4, NULO = 0;
    private int puntoInicioX, puntoFinX;
    private int puntoInicioY, puntoFinY;
    private int tipoDeComponenteParaDibujar;
    private Color colorDelFondoDePantalla;
    private String nombreArchivo;
    private BufferedImage imagen;
    private LinkedList<ComponenteGenerico> listaComponentes = new LinkedList<ComponenteGenerico>();
    private ComponenteGenerico figuraArrastrandose;
    private int posicionAnteriorDelRatonEnX;
    private int poscionANteriorDelRatonEnY;
    private Point2D posicionDeLaImagen;
    boolean archivoGuardadoUltimaVersion;

    public PantallaParaDibujar() {
        initComponents();
        introduceElComponenteConElQueSeVaADibujar(NULO);

        archivoGuardadoUltimaVersion = false;
        posicionDeLaImagen = null;
        nombreArchivo = null;     
        figuraArrastrandose = null;
        colorDelFondoDePantalla = Color.WHITE;
        setBackground(devuelveElColorDelFondoDePantalla());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     * @since 1.6
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setBackground(new java.awt.Color(255, 255, 255));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                formMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                formMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                formMouseMoved(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 810, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 471, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
        introduceElPuntoDeInicioDeX(evt.getX());  
        introduceElPuntoDeInicioDeY(evt.getY()); 
    }//GEN-LAST:event_formMousePressed

    private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
        if(tipoDeComponenteParaDibujar == devuelveUnaLinea()){
            Linea linea = new Linea(devuelveElPuntoDeInicioX(), devuelveElPuntoDeInicioY(),
                    devuelveElPuntoDeFinX(), devuelveElPuntoDeFinY());
            introducirComponenteEnLaLista(linea);
        }
        if (tipoDeComponenteParaDibujar == devuelveUnCirculo()){
            double radio = Math.sqrt(Math.pow(devuelveElPuntoDeFinX() - devuelveElPuntoDeInicioX(),2) +
                        Math.pow(devuelveElPuntoDeFinY() - devuelveElPuntoDeInicioY(),2));
            Circulo circulo =  new Circulo(devuelveElPuntoDeInicioX(),
                    devuelveElPuntoDeInicioY(), (int)radio);
            introducirComponenteEnLaLista(circulo);
            
        }
        if(tipoDeComponenteParaDibujar == devuelveUnRectangulo()){
            Rectangulo rectangulo = new Rectangulo(Math.min(devuelveElPuntoDeInicioX(), devuelveElPuntoDeFinX()),
                        Math.min(devuelveElPuntoDeInicioY(), devuelveElPuntoDeFinY()),
                        Math.abs(devuelveElPuntoDeInicioX() - devuelveElPuntoDeFinX()),
                        Math.abs(devuelveElPuntoDeInicioY() - devuelveElPuntoDeFinY()));
            introducirComponenteEnLaLista(rectangulo);
        }

    }//GEN-LAST:event_formMouseReleased

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        archivoGuardadoUltimaVersion = false;
        introduceElPuntoDeFinDeX(evt.getX());
        introduceElPuntoDeFinDeY(evt.getY());
        
        if(tipoDeComponenteParaDibujar == devuelveArrastrar()){

            if (figuraArrastrandose == null){

                posicionAnteriorDelRatonEnX = evt.getX();
                poscionANteriorDelRatonEnY = evt.getY();

                figuraArrastrandose = devuelUnComponente(evt);
            }else{
                figuraArrastrandose.devuelveLaPosicionDeInicioDelComponente((int)figuraArrastrandose.devuelveElPuntoDeInicio().getX()
                        + (evt.getX() - posicionAnteriorDelRatonEnX), (int)figuraArrastrandose.devuelveElPuntoDeInicio().getY()
                        + (evt.getY() - poscionANteriorDelRatonEnY));

                posicionAnteriorDelRatonEnX = evt.getX();
                poscionANteriorDelRatonEnY = evt.getY();

                repaint();
            }
        }
        repaint();
    }//GEN-LAST:event_formMouseDragged

    private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved
        figuraArrastrandose = null;
    }//GEN-LAST:event_formMouseMoved

    private void formMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseExited
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }//GEN-LAST:event_formMouseExited

    private void formMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseEntered

    }//GEN-LAST:event_formMouseEntered

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked

    }//GEN-LAST:event_formMouseClicked

    public int devuelveElPuntoDeFinX() {
        return puntoFinX;
    }

    public void introduceElPuntoDeFinDeX(int puntoFinDeX) {
        if(puntoFinDeX >= MINIMO_LARGO_PANTALLA_DIBUJO
                && puntoFinDeX <= MAXIMO_LARGO_PANTALLA_DIBUJO){
           this.puntoFinX = puntoFinDeX;
        }
    }

    public int devuelveElPuntoDeFinY() {
        return puntoFinY;
    }

    public void introduceElPuntoDeFinDeY(int puntoFinDeY) {
        if(puntoFinDeY >= MINIMO_ANCHO_PANTALLA_DIBUJO
                && puntoFinDeY <= MAXIMO_ANCHO_PANTALLA_DIBUJO){
            this.puntoFinY = puntoFinDeY;
        }
    }

    public int devuelveElPuntoDeInicioX() {
        return puntoInicioX;
    }

    public void introduceElPuntoDeInicioDeX(int puntoInicioDeX) {
        if(puntoInicioDeX >= MINIMO_LARGO_PANTALLA_DIBUJO
                && puntoInicioDeX <= MAXIMO_LARGO_PANTALLA_DIBUJO){
            this.puntoInicioX = puntoInicioDeX;
        }
    }

    public int devuelveElPuntoDeInicioY() {
        return puntoInicioY;
    }

    public void introduceElPuntoDeInicioDeY(int puntoInicioDeY) {
        if(puntoInicioDeY >= MINIMO_ANCHO_PANTALLA_DIBUJO
                && puntoInicioDeY <= MAXIMO_ANCHO_PANTALLA_DIBUJO){
            this.puntoInicioY = puntoInicioDeY;
        }
    }

    public Color devuelveElColorDelFondoDePantalla() {
        return colorDelFondoDePantalla;
    }

    public void introduceElColorDelFondoDePantalla(Color colorFondoPantalla) {
        this.colorDelFondoDePantalla = colorFondoPantalla;
    }

    public Point2D devuelveLaPosicionDeLaImagenEnLaPantalla(){
        return posicionDeLaImagen;
    }

    public void introduceLaPosicionDeLaImagenEnLaPantalla(Point2D imageLocation){
        this.posicionDeLaImagen = imageLocation;
        repaint();              
    }

    public int devuelveElTipoDeComponenteParaDibujar() {
        return tipoDeComponenteParaDibujar;
    }

    public void introduceElComponenteConElQueSeVaADibujar(int tipoDeComponenteDibujo) {
        this.tipoDeComponenteParaDibujar = tipoDeComponenteDibujo;
    }

    
    public BufferedImage devuelveLaImagenActual(){
        return imagen;
    }

    public static int devuelveArrastrar() {
        return ARRASTRAR;
    }

    public static int devuelveUnCirculo() {
        return Circulo;
    }

    public static int devuelveUnaLinea() {
        return Linea;
    }

    public static int devuelveUnRectangulo() {
        return Rectangulo;
    }

    public void introduceElNombreDelArchivo(String nombreDelArchivo) {
        this.nombreArchivo = nombreDelArchivo;
    } 
   
    public void introducirComponenteEnLaLista(ComponenteGenerico componente){
        listaComponentes.add(componente);
    }

    private ComponenteGenerico devuelUnComponente(MouseEvent e){
        for (ComponenteGenerico componente : listaComponentes){
            if (componente.devuelveSiEstaDentroElPunto(e.getX(), e.getY())){
                return componente;
            }
        }
        return null;
    }


    public void dibujarComponente(Graphics g){
        for (ComponenteGenerico componente : listaComponentes){
            componente.dibujar(g);
        }
    }

    public String devuelveElNombreDelDibujo() {
        return nombreArchivo;
    }

    public final BufferedImage devuelveDibujo() {
        return imagen;
    }

    public final void introducirDibujo(Image imagen) {
        this.imagen = (BufferedImage) imagen;
        introduceLaPosicionDeLaImagenEnLaPantalla(null);
        repaint();
    }

    public final void introducirDibujo(File dibujo) {
        try {
            introducirDibujo(ImageIO.read(dibujo));
        } catch (IOException falloAlLeerLaImagen) {
            System.out.println(falloAlLeerLaImagen);
        }
        repaint();
    }

    @Override
    public void paint(Graphics g){
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D)g;

        if (devuelveLaImagenActual() != null){
            Point2D center = new Point2D.Double(getWidth() / 2, getHeight() / 2);
            if (devuelveLaPosicionDeLaImagenEnLaPantalla() != null){
                center = devuelveLaPosicionDeLaImagenEnLaPantalla();
            }
            Point2D loc = new Point2D.Double();
            double width = imagen.getWidth();
            double height = imagen.getHeight();
            loc.setLocation(center.getX() - width / 2, center.getY() - height / 2);
            g.drawImage(devuelveLaImagenActual(), (int) loc.getX(), (int) loc.getY(),(int) width, (int) height, null); // centra la imagen
        }
        dibujarComponente(g);
        
       
            if (tipoDeComponenteParaDibujar == devuelveUnaLinea()) {
                Line2D line2D = new Line2D.Float(devuelveElPuntoDeInicioX(),
                    devuelveElPuntoDeInicioY(), devuelveElPuntoDeFinX(), devuelveElPuntoDeFinY());
                g2 = (Graphics2D)g;
            
                g2.draw(line2D);
            }

           
            if (tipoDeComponenteParaDibujar == devuelveUnCirculo()){
                double radio = Math.sqrt(Math.pow(devuelveElPuntoDeFinX() - devuelveElPuntoDeInicioX(),2) +
                        Math.pow(devuelveElPuntoDeFinY() - devuelveElPuntoDeInicioY(),2));
                Ellipse2D e2;
               

                e2 = new Ellipse2D.Float(devuelveElPuntoDeInicioX() - (int)radio, devuelveElPuntoDeInicioY() - (int)radio,
                    (int)radio * 2 , (int)radio * 2);
                g2 = (Graphics2D)g;
               
                g2.draw(e2);
            }

            if (tipoDeComponenteParaDibujar == devuelveUnRectangulo()){
                
                Rectangle2D r2;
                
                r2 = new Rectangle2D.Float(Math.min(devuelveElPuntoDeInicioX(), devuelveElPuntoDeFinX()),
                        Math.min(devuelveElPuntoDeInicioY(), devuelveElPuntoDeFinY()),
                        Math.abs(devuelveElPuntoDeInicioX() - devuelveElPuntoDeFinX()),
                        Math.abs(devuelveElPuntoDeInicioY() - devuelveElPuntoDeFinY()));
                g2 = (Graphics2D)g;
                
                g2.draw(r2);
            }

            
    }

    public void crearDibujo() {
        imagen = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D grafico2D = imagen.createGraphics();
        grafico2D.setColor(Color.WHITE);
        grafico2D.fillRect(0, 0, this.getWidth(), this.getHeight());
        dibujarComponente(grafico2D);
        introducirDibujo(imagen);
        grafico2D.dispose();
        introducirDibujo(imagen);
        repaint();
    }

    public void abrirDibujo(String NombreDelDibujo) {
        ConexionJDBCMySQL.sacarImagenBBDD(NombreDelDibujo);
        String ruta =  NombreDelDibujo + ".png";
        File dibujo = new File(ruta);
        try{
            imagen = ImageIO.read(dibujo);
        } catch (IOException noLeLaImagen){
        }
        introducirDibujo(imagen);
        Graphics grafico = imagen.getGraphics();
        introduceElColorDelFondoDePantalla(Color.WHITE);
        introduceElNombreDelArchivo(NombreDelDibujo + "_1");
        grafico.drawImage(imagen, 0, 0, this);
        repaint();
    }

    public void guardarLienzo() {
        File archivo = new File(devuelveElNombreDelDibujo() + ".png");
        if (imagen == null) {
            crearDibujo();
        }
        try {
            ImageIO.write(devuelveDibujo(), "png", archivo);
        } catch (IOException noGuardaElFichero) {
        }
        ConexionJDBCMySQL.guardarImagenEnBBDD(devuelveElNombreDelDibujo());
        ConexionJDBCMySQL.borrarImagenDeDisco(devuelveElNombreDelDibujo());
        listaComponentes.clear();
        repaint();
    }
 }


    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

